<?php

namespace App\Repositories;

use App\Models\SmsCode;

/**
 * 短信验证码仓库
 * @property SmsCode $model
 * @method SmsCode create(array $data) 创建短信验证码
 * @method SmsCode|null getById(int $id)
 */
class SmsCodeRepository extends BaseRepository
{
    public function __construct(SmsCode $model)
    {
        parent::__construct($model);
    }

    public function getByKey(string $key): ?SmsCode
    {
        return $this->query()
            ->where('key', $key)
            ->first();
    }

    /**
     * 检查短信验证码是否正确
     * @param string $key
     * @param string $code 短信验证码
     * @return bool
     */
    public function check(string $key, string $code): bool
    {
        $smsCode = $this->getByKey($key);
        if (!$smsCode) {
            abort(403, '短信验证码不存在');
        }

        if ($smsCode->is_used) {
            abort(403, '短信验证码已被使用');
        }

        if ($smsCode->expired_at->lt(now())) {
            abort(403, '短信验证码已过期');
        }

        if ($smsCode->code !== $code) {
            $smsCode->attempts++;
            $smsCode->save();
            abort(403, '短信验证码错误');
        }

        $smsCode->is_used = true;
        $smsCode->passed_at = now();
        $smsCode->save();
        return true;
    }

    /**
     * 获取短信验证码
     * @param string $guard 守卫
     * @param string $phone 手机号
     * @return SmsCode|null
     */
    public function get(string $guard, string $phone): ?SmsCode
    {
        return $this->query()
            ->where('guard', $guard)
            ->where('phone', $phone)
            ->first();
    }


    /**
     * 发送短信验证码
     * @param string $guard 守卫
     * @param string $phone 手机号
     * @return SmsCode
     */
    public function sendShortMessage(string $guard, string $phone): SmsCode
    {
        $smsCode = $this->create([
            'guard' => $guard,
            'phone' => $phone,
            'key' => uuid(),
            'code' => code(),
            'expired_at' => now()->addMinutes(5),
            'attempts' => 0,
            'is_used' => false,
        ]);


//        if (! app()->environment('local')) {
//            $result = app(ShortMessageService::class)->sendVerificationCode($phone, $smsCode->code);
//            if (!$result) {
//                abort(403, '短信验证码发送失败');
//            }
//        }

        return $smsCode;
    }

    public function throttle(string $guard, string $phone): int
    {
        return $this->query()
            ->where('guard', $guard)
            ->where('phone', $phone)
            ->where('created_at', '>=', now()->subMinutes(5))
            ->count();
    }
}
